The Let's Play Archive

Tales of Vesperia

by Admiral H. Curtiss

Part 161: Vesperia Hacking - Area Names

Vil posted:

I always enjoy a good nerdy curiosity when it comes to hacking tricks.

Note: The following is pretty technical, so if you're not incredibly interested in ToV's internal data structures just skip it.


Tales of Vesperia's game files are split into a couple archives, mostly *.svo files. The textures for things like the menu, the item icons, the font, and the area names are stored in UI.svo. We're going to take a look at those area names and how the game displays them today.

Each area name texture is stored in a texture named "TOWNMAP***.TXV", where the * are a three or four letter code for each area. For example, here's the textures in TOWNMAPCAP.TXV:



So how does the game get those on-screen, exactly? To figure that out we have to open up another archive: scenario.dat

scenario.dat contains event data, which is mostly data relating to cutscenes or non-standard NPCs (ie, ones that cause specific events or minigames or whatever to happen). scenario.dat contains 1475 (PS3 version) different, individually compressed and unnamed TSS scripts, which seems to be something Namco Tales Studio specific. I eventually found something like filenames for them in another archive (MAPLIST.DAT in map.svo), but originally I had more or less no idea which file was responsible for what -- the best thing I could do was guess based on dialogue strings in them.

At first I assumed that the data for those town images had to be in the file that contained cutscene dialogue for the scene where they show up. After randomly editing values in them and getting various effects from characters moving to different spots to the game outright crashing, I eventually figured that it had to be somewhere else.

As it turns out, the data for every single town and dungeon name image is in the very first file in scenario.dat, called "startup" by MAPLIST.DAT. I figured that out by searching for the different letter codes in the texture filenames, which lead me to a list of 0xAC sized blocks, what I call the TownMap Info table:



The important things here are the first couple bytes, the filename it reads the texture from, and the last eight, the amount of "tiles" or "letters" to process. Two 32bit integers, one for the Japanese texture and one for the English texture. Pretty much all language-specific content in Vesperia is stored in that way, with entries for two languages within the same file. (and yes, nearly all text and images from the English 360 version is still in the Japanese PS3 version, just inaccessible under normal circumstances) The rest is data like the screen coordinates to start rendering and the location and color for the background glow -- I didn't experiment too much with that since none of it is actually related to the actual letters it displays.


It took me a bit to actually find the letters, since the way it loads this whole structure is kinda convoluted:

- The TSS file header at 0x0C contains what is presumably the start pointer/offset of the "data" section of the script. This value is used later.


- The script executes and eventually reaches the following relevant section containing several pointers relative to the start of the data section:



0x156BC: Pointer to what I call the TownMap Info table. This is the structure I've already talked about above.
0x156DC and 0x15710: Pointers to what I call the TownMap Tile table. The first points at the Japanese data, while the second points at the English data. This is the data that tells the game how the individual letters/tiles are displayed.
0x156E4 and 0x15718: Pointers to what I call the TownMap Offset table. This data tells the game which of the tiles in the above table is the tile to start from.


The Offset table:



Eight bytes per entry, two integers. First integer for the Japanese data, second for the English data.
Both of these values tell the game how many tiles to skip before reading data in the Tile table.

So if you want the game to display 10 tiles starting at the 8th tile in the Tile table, you need to set the entry in this table to 7, and set the corresponding entry in the Info table to 10. As I said, kind of convoluted, ideally you'd automatically create these values so they match up and don't waste any space anywhere, but since all I needed to change was five entries I just did this manually.


The Tile table:



0x20 bytes per entry, 8 integers.
The first integer tells the game how many frames to wait before fading in the tile.
The second and third integers are the top left corner (X and Y) of the tile in texture, in pixels.
The fourth and fifth integers are the width and height of the tile, in pixels.
The sixth and seventh integers are the location where the tile actually gets drawn at on the screen. This is relative to some other values in the corresponding Info table entry.
The last four bytes seem to be unused.


By combining all these structures, the game eventually manages to display the area name when entering a new area.



As you might be able to imagine, it's rather hard to figure out how the end result of all this is going to look in-game without actually booting up the game and getting to the area in question for the first time. So I wrote myself a tool to approximate exactly that:



This was very useful for making the English images and display data for the new areas.

I dunno how interesting this is to any of you, but here you go.